package com.lzh.prometheus.httpclient;

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.google.gson.Gson;
import com.lzh.prometheus.pojos.dingding.DingDingMarkdownNotice;
import com.lzh.prometheus.pojos.dingding.DingDingNotice;
import com.lzh.prometheus.pojos.dingding.DingDingResult;
import com.lzh.prometheus.pojos.dingding.DingDingTextNotice;
import com.lzh.prometheus.properties.enums.DingdingTextTypeEnum;
import com.lzh.prometheus.properties.notice.DingDingNoticeProperty;
import com.taobao.api.ApiException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @author zhehen.lu
 * @date 2025/8/15 9:25
 */
public class DefaultDingdingHttpClient implements DingdingHttpClient {

    private final DingDingNoticeProperty dingDingNoticeProperty;

    private final Log logger = LogFactory.getLog(getClass());

    /**
     * @param gson
     * @param dingDingNoticeProperty
     */
    public DefaultDingdingHttpClient(Gson gson, DingDingNoticeProperty dingDingNoticeProperty) {
        this.dingDingNoticeProperty = dingDingNoticeProperty;
    }

    @Override
    public DingDingResult doSend(DingDingNotice body) throws ApiException {
        logger.debug("发送钉钉请求:" + body);
        String serverUrl = "https://oapi.dingtalk.com/robot/send";
        if (dingDingNoticeProperty.isEnableSignatureCheck()) {
            long timestamp = System.currentTimeMillis();
            serverUrl = serverUrl + "?sign=" +
                    generateSign(System.currentTimeMillis(), dingDingNoticeProperty.getSignSecret())
                    + "&timestamp=" + timestamp;
        }
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest req = new OapiRobotSendRequest();

        switch (DingdingTextTypeEnum.getEnumByValue(dingDingNoticeProperty.getDingdingTextType().getMsgType())) {
            case TEXT:
                //定义文本内容
                OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
                DingDingTextNotice dingNotice = (DingDingTextNotice) body;
                text.setContent(dingNotice.getText().getContent());
                req.setText(text);
                break;
            case MARKDOWN:
                OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
                DingDingMarkdownNotice dingMarkdownNotice = (DingDingMarkdownNotice) body;
                markdown.setTitle(dingMarkdownNotice.getMarkdown().getTitle());
                markdown.setText(dingMarkdownNotice.getMarkdown().getText());
                req.setMarkdown(markdown);
                break;
        }
        //定义 @ 对象
        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setIsAtAll(body.getAt().isAtAll());
        at.setAtMobiles(Arrays.stream(body.getAt().getAtMobiles()).collect(Collectors.toList()));
        //设置消息类型
        req.setMsgtype(dingDingNoticeProperty.getDingdingTextType().getMsgType());
        req.setAt(at);
        OapiRobotSendResponse rsp = client.execute(req, dingDingNoticeProperty.getAccessToken());
        return JSON.parseObject(JSON.toJSONString(rsp), DingDingResult.class);
    }

    protected String generateSign(Long timestamp, String sec) {
        String combine = String.format("%d\n%s", timestamp, sec);
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(sec.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signData = mac.doFinal(combine.getBytes("UTF-8"));
            return Base64.encodeBase64String(signData);
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

}